// 1.对象响应化：遍历每个key，定义getter、 setter
// 2.数组响应化：覆盖数组原型⽅法，额外增加通知逻辑
const originalProto = Array.prototype
const arrayProto = Object.create(originalProto);
   ['push', 'pop', 'shift', 'unshift', 'splice', 'reverse', 'sort'].forEach(
        method => {
            arrayProto[method] = function () {   //这里修改覆盖 新arrayProto对应的每一个方法
                originalProto[method].apply(this, arguments)//originalProto[method] 调用原来的方法，如Array的push
                notifyUpdate(arguments[0],method) //加入自己想要派发的信息
            }
        }
    )
    /*等价于
    copyProto['push'] = function() {
        orginalProto['push'].call(this,arguments)
        notifyUpdate.log("test..")
    }
    */
  //观察方法 主入口
  function observe(obj) {
    if (typeof obj !== 'object' || obj == null) {
        return
    }
    // 增加数组类型判断，若是数组则覆盖其原型
    if (Array.isArray(obj)) {
        // Object.setPrototypeOf(obj, arrayProto) 
     obj.__proto__ = arrayProto
      for (let index = 0; index < obj.length; index++) {
        observe(obj[index]);//继续递归处理
      } 


    } else {
        const keys = Object.keys(obj)
        for (let i = 0; i < keys.length; i++) {
            const key = keys[i]
            defineReactive(obj, key, obj[key])
        }
    }
}
//响应式逻辑
function defineReactive(obj, key, val) {
    observe(val) // 解决嵌套对象问题
    Object.defineProperty(obj, key, {
        get() {
            return val
        },
        set(newVal) {
            if (newVal !== val) {
                observe(newVal) // 新值是对象的情况
                val = newVal
                notifyUpdate(val)
            }
        }
    })
}
function notifyUpdate(val) {
    console.log(val,'⻚⾯更新!')
}  

var testObj = {name:"jason"}
observe(testObj)
testObj.name = "jason.yang"


var testArray = [{name:"jason1"},{name:"jason2"}]
observe(testArray)
testArray.push({name:"jason3"})

testArray[0].name = "jason4"